### chap1 
a<-1
a = 2
a <- 2
b= 3

ls()  #列出对象
ls.str()  #对象基本信息

## ls函数
# 1. ls()函数列出所有变量

#2. 模式匹配
ls(pattern="var")  #所有含有var的变量
rm(a) #删除对象

#3. 以.开始的变量是隐藏的，使用all.names=True 参数来使其显示
ls(all.name=TRUE)

ls  #没有双括号，将显示该函数的内容 (代码)

library()  #查找已经安装的包
library("gtools")  #加载包
search()  #查看已经加载的包

#帮助
?ls
help("ls")

-------------

### chap2 数据读入与整理

vector("numeric", 10)
vector("logical", 10)

numeric(5)
character(3)
?numeric

f <- factor(5:10)
as.numeric(f)
as.numeric(as.character(f))
as.numeric(levels(f))[f]

# 查看数据类型
a <- c(1, 2, 3)
mode(a)  #"numeric"
b <- c("china", "usa", "france")
mode(b)  # "character"

# 因子 (名义变量和有序变量可以使用因子来表示)
a <- factor(1:3)
b <- factor(1:3,levels=1:5)
d <-factor(1:3,labels=c('A','B','C'))

# 时间序列数据
ts(1:10, frequency = 4, start = c(1959, 2))
g <- ts(1:47, frequency = 12, start = c(1959, 2))
print(g,calendar=T)
print(g)

#数组
array(0,dim=c(2,3,2))
z <- array(1:12, dim=c(2,3,2))
dim(z)

#矩阵
matrix(1:12, nrow=2,byrow=T)  #byrow:矩阵的元素是否按行填充，默认为False(按列填充)
matrix(1:12, 4,3,dimnames = list(c('a','b','c','d'),c('e','f','g')))

#列表
Lst <- list(name="Fred", wife="Mary",no.children=3, child.ages=c(4,7,9))
Lst
a <- 1:3; b <- letters[1:7]; c(a,b); list(a,b)


set.seed(250) #随机种子
a = runif(3,min=0,max=100) #均匀分布随机数
# rnorm正态分布 rexp 指数分布 ...
floor(a)   #不大于该数的最大整数
ceiling(a)   #不小于该数的最小整数
round(a,4)  #保留4位小数

rnorm(3)


getwd() #查看工作路径

#读入数据
?"read.xlsx"
??map

library('purrr')
library("openxlsx")
# detach("package:purrr")

data1=read.xlsx("C:/repos/Fyr-learning/data/rank.xlsx",sheet=1)  #直接读取

#读取多个列表的方式
name_sheet=1:10  
re=map(name_sheet, ~read.xlsx("C:/repos/Fyr-learning/data/rank.xlsx",sheet=.))
str(re)  #检查数据框中有哪些数据
re[[1]]

#生成序列数据
1:10
seq(1,10,0.5)
1:10-1  #整体-1

#生成重复数据 rep函数
rep(1,10)
rep(1:2,10)
rep(1:2,each=10)

edit(data1)  #调用文本编辑器修改数据对象
fix(data1)  #会改变data1
data.entry(data1)   #用data.entry()修改了数据框，会转换成列表(list)类型
ls.str(data1)  #详细情况
str(data1)   #数据类型和详细情况



#####子集提取

x <- 1:100
mode(x)
x[1:10]

#向量
x = c(1,2,3,4,5)
x
x[1]
x[1:4]
x[c(1,5)]
x[-2]  #除了2之外的元素
x[2] = 7 #改变第二个元素的值
x

#矩阵
a<-matrix(1:30,6,5,byrow = T)
a
a[1,2]  #第一行第二列
a[2,] #第二行
a[2,c(3,5)]

#列表
lst <- list(name="Fred", wife="Mary",no.children=3, child.ages=c(4,7,9))
names(lst)
lst[1]
lst[[1]]
lst[[4]][2]
lst$wife
lst['wife']  #输出元素内容及其名称

##数据对象合并
class1 <- data.frame(name=c('Tom','Marry','Bob','Mike','Lily'),hight=c(170,165,175,180,158))
class2 <- data.frame(name=c('Lee','Judy','Max','Owen','Jack'),hight=c(170,167,183,185,177))
class3=data.frame(name=c('Jackson','Iris','Edison','Rose','Annie','Julie'),score=c(66,77,76,78,90,89))
class1.1 <- data.frame(name=c('Jackson','Owen','Bob','Mike','Lily'),score=c(90,85,75,80,90))

#rbind 行合并
rbind(class1,class2) #要求字段名称相同

#bind_rows函数(dplyr包)
library(dplyr)
bind_rows(class1,class3)  #对字段名称不同的数据自动补全

#cbind 列合并 （单纯的横向拼接
cbind(class1,class1.1)

#merge 关键字合并
merge(class1,class1.1,by = 'name',all=T)
merge(class1,class1.1,by = 'name',all=F)  #缺失部分数据的不要
merge(class1,class1.1,by = 'name',all.x=T)  #保留x数据集中的id

#join函数（dplyr包）
full_join(class1,class1.1,by='name')
inner_join(class1,class1.1,by='name')  #缺失部分数据的不要
left_join(class1,class1.1,by='name') #左合并　
right_join(class1,class1.1,by='name') #右合并




# %>% 的含义
## ％>％来自dplyr包的管道函数，其作用是将前一步的结果直接传参给下一步的函数，从而省略了中间的赋值步骤，可以大量减少内存中的对象，节省内存
df %>% select(where(~!any(is.na(.))))

#select函数
packageVersion("dplyr")
library(dplyr)
data(iris)
names(iris)
select(iris,Species) #根据列名选择列
select(iris,Sepal.Width:Petal.Width) #选择连续列

#根据index选择列
select(iris,1,2)
select(iris,1:3)

#对选择后的列进行命名
new_iris <- select(iris, Class= Species)
names(new_iris)

#交换列的顺序
new_iris <- select(iris,5,1)
names(new_iris)


#apply函数：apply()按矩阵的行或列方向应用指定函数
s <- matrix(1:9,ncol = 3)
apply(s,1,sum)  #按行加和
apply(s,2,sum)

#lapply函数 用于对列表对象执行操作，并返回与原始集合长度相同的列表对象
b = list(x=1:10,y=matrix(1:12,3,4))
b
lapply(b,sum)

#sapply函数 输入为列表，输出为向量
b = list(x=1:10,y=matrix(1:12,3,4))
sapply(b,sum)

#tapply函数 将数据按照不同方式分组,产生类似列联表的形式
manage = c(1,2,3,4,5)
country = c('us','us','uk','uk','uk')
gender <- c("M", "F", "F", "M", "F")
age <- c(32, 45, 25, 39, 99)
leadership <- data.frame(manager, country, gender, age)
tapply(leadership$age, leadership$country, mean) #不同country水平下age的均值
tapply(leadership$age, list(leadership$country, leadership$gender), mean) #在不同country和gender的交叉水平下age均值

#by函数 根据类别对数据使用函数
df = data.frame(x=c(1:5),y=c(1,2,5,6,8),id=c('a','a','b','b','c'))
by(df,df$id,summary)

#with函数
a='out'
df=data.frame(x=c(1,2,3),y=c(5,6,7))
with(df,{
    a=x+y
    b=x-y
    print(c(a,b))
})
a  #括号中的变量是局部变量



#### aggregate函数，类似groupby
x=data.frame(name=c('张三','李四','王五','赵'),sex=c('f','m','f','m'),age=c(20,30,40,25),height=c(166,170,150,155))
aggregate(x[,3:4],by=list(sex=x$sex),FUN=mean)  #按性别求平均




##删除缺失值
#去除所有值都是NA的行
df[apply(df,1,function(x) !all(is.na(x))),]

#去掉包含NA的行
df2 <- na.omit(df)

#去掉包含NA的列
df %>% select(where(~!any(is.na(.))))

#优先选国内的镜像 install.package
#调用包 library（）
# 大小写敏感 有差异
#清除变量 rm(list=ls())
cumsum()  #累计求和
cumprod()  #累计求乘积
rev()  #倒序
a*b #矩阵相对位置相乘
a%*%b #矩阵的乘法

cat() #每一个都展现出来 
print() 
paste() #按列输出
return()

#变量运用时的固定命令
attach() #调用数据前面用该行数 变量专指该数据集
detach() #解除attach
#变量前面已经出现 后面attach到的变量调用不出来
###with解决上述问题
with(mtcars,{plot(mpg,wt)})
#with局限性在于 赋值仅在函数括号内生效
#用<<-代替<- 可以将对象保存到全局环境中

#控制语句 循环语句
x = c(5,4,2,8,9,10)
n = length(x)
sort.x <- sort(x)
if (n%%2==0) {
    median <- (sort.x[n/2]+sort.x[1+n/2])/2
} else {
   median <- sort.x[(n+1)/2]
}
median

#计算10的阶乘
f <-1
for (i in 1:10){
    f <- f*i
    print(c(i,f),'/n')
}
f
factorial(10)

sample(1:10,10,replace = FALSE)  #不放回抽样

#paste函数 用于字符串连接
paste('a','b')
paste('a','b',sep='=') 
paste('a',1:5,sep='') #每个元素自动与a相连
paste(c('a','b','c'))
paste(c('a','b','c'),collapse = '+')
paste('a',1:5,sep='',collapse = '+')  #collapse参数是增加在元素间，与sep有一定区别

#paste0 默认元素连接的sep=''

#函数式编程
addnum<- function(x,y){
    s<-x+y
    return(s)
}
addnum(3,4)
addnum  #输入函数名可以查看函数定义
body(addnum) #检查函数体
formals(addnum) #检查形式参数
args(addnum) #函数个数
environment(addnum)  #全局空间



##r语言作图
demo(graphics)

data(iris)
head(iris)
summary(iris)
pie(table(iris$Species))  #饼图

#直方图
hist(iris$Sepal.Length)
hist(iris$Sepal.Length, breaks=15)    #指定柱子的条数
hist(iris$Sepal.Length, prob=T)     #y轴变成百分比

#柱状图
barplot(table(iris$Sepal.Length), col=rainbow(dim(table(iris$Sepal.Length))))
barplot(table(iris$Sepal.Length), col=rainbow(dim(table(iris$Sepal.Length))), horiz=T)  #柱子方向设为横向

#散点图
plot(iris$Sepal.Length)                     
plot(iris$Sepal.Length, iris$Sepal.Width)

#密度图
plot(density(iris$Sepal.Length))
hist(iris$Sepal.Length, prob=T)
lines(density(iris$Sepal.Length),col=3,lwd=4) #在密度图上加上平滑曲线

#箱线图
boxplot(iris$Sepal.Length)               #竖直的箱型图
boxplot(iris$Sepal.Length, horizontal=T) #水平的箱型图

#变量两两间散点图
plot(iris[,1:4])   
pairs(iris[,1:4])  #与上句等价

x <- rnorm(100)
# Calculate and plot the two histograms
hcum <- h <- hist(x, plot=FALSE)
hcum$counts <- cumsum(hcum$counts)  #累计求和
plot(hcum, main="")
plot(h, add=T, col="grey")
# Plot the density and cumulative density
d <- density(x)
lines(x = d$x, y = d$y * length(x) * diff(h$breaks)[1], lwd = 1, col="red")
lines(x = d$x, y = cumsum(d$y)/max(cumsum(d$y)) * length(x), lwd = 1, col="blue")

###par函数 该函数参数除个别外一旦设定，除非再次更改或重启R，否则就会对后续所有的绘图命令起作用
opar <- par(no.readonly = TRUE)  #储存r默认作图参数
par(opar)
plot(1:10)
# 查看当前参数的值
par("usr")
par(c("usr", "fin"))

#设置图像布局
par(mfcol=c(1,2))   #一行两列
par(mfrow=c(2,1))

par(fig=c(0,0.6,0.5,1)) # c(x1, x2, y1, y2)，横向范围0~0.6，纵向范围0.5~1
plot(1:100)
 
opar<-par(no.readonly = TRUE)
par(fig=c(0,0.8,0,0.9))
plot(mtcars$wt,mtcars$mpg,xlab = "miles per callon",
     ylab = "Car Weight")
par(fig=c(0,0.8,0.50,1),new=TRUE)
boxplot(mtcars$wt,horizontal = TRUE,axes=FALSE)
par(fig=c(0.65,1,0,0.8),new=TRUE)
boxplot(mtcars$mpg,axes=FALSE)

?par
##参数
#oma：参数形式为c(bottom, left, top, right)，用于设定外边界。
#mgp：设定标题、坐标轴名称、坐标轴距图形边框的距离。默认值为c(3,1,0)，其中第一个值影响的是标题。
#mar : 形式为c（bottom, left, top, right），给出绘图四边指定的边距行数。默认值为c（5，4，4，2）+0.1。

#abline() 添加直线  col:线条的颜色, lty :线条的类型,lwd:线条的宽度
plot(1:5, 1:5, xlim = c(0,6), ylim = c (0,6))
abline(h = 0, col = "red",lwd = 2, lty = 2)


##segment函数
plot(0, 0, col = "white", xlab = "", ylab = "")
segments(x0 = - 1, y0 = - 0.5, x1 = 0.5, y1 = 0, col = "darkgreen") 